package cnpm02.j2ee.group3.logic.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.faces.model.SelectItem;

import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.log.Log;

import cnpm02.j2ee.group3.logic.dao.impl.EmailTemplateDao;
import cnpm02.j2ee.group3.logic.dao.impl.LanguageDao;
import cnpm02.j2ee.group3.logic.dao.impl.LanguageTranslationDao;
import cnpm02.j2ee.group3.logic.dao.impl.NationalityDao;
import cnpm02.j2ee.group3.logic.dao.impl.NationalityTranslationDao;
import cnpm02.j2ee.group3.logic.dao.impl.PersonDao;
import cnpm02.j2ee.group3.logic.dao.impl.SecretQuestionDao;
import cnpm02.j2ee.group3.logic.dao.impl.SecretQuestionTranslationDao;
import cnpm02.j2ee.group3.logic.utils.ATSMUtils;
import cnpm02.j2ee.group3.logic.utils.DESUtil;
import cnpm02.j2ee.group3.logic.validator.CustomEmail;
import cnpm02.j2ee.group3.logic.validator.NumberOnly;
import cnpm02.j2ee.group3.logic.validator.Unique;
import cnpm02.j2ee.group3.model.EmailTemplate;
import cnpm02.j2ee.group3.model.Gender;
import cnpm02.j2ee.group3.model.Language;
import cnpm02.j2ee.group3.model.LanguageTranslation;
import cnpm02.j2ee.group3.model.Nationality;
import cnpm02.j2ee.group3.model.NationalityTranslation;
import cnpm02.j2ee.group3.model.Person;
import cnpm02.j2ee.group3.model.PhoneNumber;
import cnpm02.j2ee.group3.model.SecretQuestion;
import cnpm02.j2ee.group3.model.SecretQuestionTranslation;

@Name("person")
public class NewPerson implements Serializable {
	private static final long serialVersionUID = 1L;
	private static final String REGISTER_EMAIL_TEMPLATE_CODE = "RES";

	@In
	private ATSMUtils atsmUtils;
	@In
	private NationalityDao nationalityDao;
	@In
	private NationalityTranslationDao nationalityTranslationDao;
	@In
	private SecretQuestionDao secretQuestionDao;
	@In
	private SecretQuestionTranslationDao secretQuestionTranslationDao;
	@In
	private LanguageDao languageDao;
	@In
	private LanguageTranslationDao languageTranslationDao;
	@In
	private PersonDao personDao;
	@In
	private EmailTemplateDao emailTemplateDao;
	@Logger
	private Log log;
	
	private List<SelectItem> languages = new ArrayList<SelectItem>();
	private List<SelectItem> nationalities = new ArrayList<SelectItem>();
	private List<SelectItem> days = new ArrayList<SelectItem>();
	private List<SelectItem> months = new ArrayList<SelectItem>();
	private List<SelectItem> birthdayYears = new ArrayList<SelectItem>();
	private List<SelectItem> secretQuestions = new ArrayList<SelectItem>();
	private List<SelectItem> paymentWays = new ArrayList<SelectItem>();
	private List<SelectItem> cardExpiredYears = new ArrayList<SelectItem>();
	private List<SelectItem> genders = new ArrayList<SelectItem>();
	private List<SelectItem> nationalPhoneCodes = new ArrayList<SelectItem>();
	
	@Unique(sql = "from Person p where p.login = :login", parameterName = "login", message = "{validator.uniqueLogin}")
	private String login;
	private String lastNameAndSubName;
	private String firstName;
	private String password;
	private String confirmPassword;
	private boolean allowedAdvertising;
	private boolean allowedBroadCastInformation;
	private String answer;
	
	private String selectedLanguage;
	private String selectedNationality;
	private Date selectedBirthDay;
	private Date selectedPaymentCardExpired;
	private String selectedSecretQuestion;
	private String selectedGender;
	private String selectedNationalCode;
	
	//phone and Email
	private String mNationalCode;//Mobile phone
	@NumberOnly
	private String mAreaCode;
	@NumberOnly
	private String mNumberPhone;
	private String pNationalCode;//Personal phone
	@NumberOnly
	private String pAreaCode;
	@NumberOnly
	private String pNumberPhone;
	
	@CustomEmail
	private String email;
	private String confirmationEmail;
	
	@Create
	public void init() {
		//Initialize language
		for (LanguageTranslation l : languageTranslationDao
				.selectAllByLocale(atsmUtils.getCurrentLanguage())) {
			languages.add(new SelectItem(String.valueOf(l.getLanguage().getId()), l
					.getTranslation()));
		}
		
		//Initialize nationality list and national codes
		int code = 0;
		for (NationalityTranslation n : nationalityTranslationDao
				.selectAllByLocale(atsmUtils.getCurrentLanguage())) {
			getNationalities().add(
					new SelectItem(String.valueOf(n.getNationality().getId()), n
							.getTranslation()));
			getNationalPhoneCodes().add(
					new SelectItem(String.valueOf(++code), n.getTranslation()));
		}
		
		//Initialize secret question list
		for (SecretQuestionTranslation s : secretQuestionTranslationDao
				.selectAllByLocale(atsmUtils.getCurrentLanguage())) {
			getSecretQuestions().add(
					new SelectItem(String.valueOf(s.getSecretQuestion().getId()), s
							.getTranslation()));
		}
		
		//Initialize payment way
		for(String str : atsmUtils.getPaymentWays()) {
			paymentWays.add(new SelectItem(str, str));
		}
		
		//Initialize expired day
		List<Integer> lsYears = atsmUtils.getYears(Calendar.getInstance().get(Calendar.YEAR) + 10);
		for (Integer i : lsYears) {
			getCardExpiredYears().add(new SelectItem(i.toString(), i.toString()));
		}
		
		//Genders
		for(Gender g : Gender.values()) {
			getGenders().add(new SelectItem(g.toString(), g.getNameByLanguage(atsmUtils.getCurrentLanguage())));
		}
		
		mNationalCode = nationalPhoneCodes.get(0).getValue().toString();
		pNationalCode = nationalPhoneCodes.get(0).getValue().toString();
		log.debug("Finish initializing person");
	}
	
	public String doSave() {
		Gender g = Gender.valueOf(selectedGender);
		Nationality n = nationalityDao.find(Long.valueOf(selectedNationality));
		Language l = languageDao.find(Long.valueOf(selectedLanguage));
		SecretQuestion s = secretQuestionDao.find(Long.valueOf(selectedSecretQuestion));
		
		PhoneNumber phone = new PhoneNumber(selectedNationalCode
				.toString(), pAreaCode + pNumberPhone);
		
		DESUtil des = DESUtil.getInstance();
		Person person = new Person(firstName, lastNameAndSubName,
				selectedBirthDay, g, n, l, s, answer, phone, email, login,
				des.encrypt(password), allowedAdvertising,
				allowedBroadCastInformation);
		person.setKey(des.getKey());
		personDao.saveOrUpdate(person);
		
		//Set successful email
		log.debug("Sending mail...");
		EmailTemplate et = emailTemplateDao.getEmailTemplate(REGISTER_EMAIL_TEMPLATE_CODE,
				l.getCode());
		String subject = et.getSubject();
		String content = String.format(et.getContent(), firstName, firstName,
				login, password);
		atsmUtils.sendMail(email, subject, content);
		log.debug("Create new person successfully!");
		return "success";
	}
	
	public List<SelectItem> getMonths() {
		return months;
	}

	public List<SelectItem> getLanguages() {
		return languages;
	}

	public List<SelectItem> getNationalities() {
		return nationalities;
	}

	public void setMonths(List<SelectItem> months) {
		this.months = months;
	}

	public List<SelectItem> getBirthdayYears() {
		return birthdayYears;
	}

	public List<SelectItem> getDays() {
		return days;
	}

	public List<SelectItem> getSecretQuestions() {
		return secretQuestions;
	}

	public void setSelectedNationality(String selectedNationality) {
		this.selectedNationality = selectedNationality;
	}

	public String getSelectedNationality() {
		return selectedNationality;
	}

	public void setSelectedLanguage(String selectedLanguage) {
		this.selectedLanguage = selectedLanguage;
	}

	public String getSelectedLanguage() {
		return selectedLanguage;
	}

//	public void setSelectedDay(String selectedDay) {
//		this.selectedDay = selectedDay;
//	}
//
//	public String getSelectedDay() {
//		return selectedDay;
//	}
//
//	public void setSelectedMonth(String selectedMonth) {
//		this.selectedMonth = selectedMonth;
//	}
//
//	public String getSelectedMonth() {
//		return selectedMonth;
//	}
//
//	public void setSelectedBirYear(String selectedBirYear) {
//		this.selectedBirYear = selectedBirYear;
//	}
//
//	public String getSelectedBirYear() {
//		return selectedBirYear;
//	}

	public void setSelectedSecretQuestion(String selectedSecretQuestion) {
		this.selectedSecretQuestion = selectedSecretQuestion;
	}

	public String getSelectedSecretQuestion() {
		return selectedSecretQuestion;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getLogin() {
		return login;
	}

	public void setLastNameAndSubName(String firstNameAndSubName) {
		this.lastNameAndSubName = firstNameAndSubName;
	}

	public String getLastNameAndSubName() {
		return lastNameAndSubName;
	}

	public void setFirstName(String lastName) {
		this.firstName = lastName;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getPassword() {
		return password;
	}

	public void setConfirmPassword(String confirmPassword) {
		this.confirmPassword = confirmPassword;
	}

	public String getConfirmPassword() {
		return confirmPassword;
	}
	
	public void setAllowedAdvertising(boolean allowedAdvertising) {
		this.allowedAdvertising = allowedAdvertising;
	}

	public boolean isAllowedAdvertising() {
		return allowedAdvertising;
	}

	public void setAllowedBroadCastInformation(boolean allowedBroadCastInformation) {
		this.allowedBroadCastInformation = allowedBroadCastInformation;
	}

	public boolean isAllowedBroadCastInformation() {
		return allowedBroadCastInformation;
	}

	public void setAnswer(String answer) {
		this.answer = answer;
	}

	public String getAnswer() {
		return answer;
	}

	public List<SelectItem> getPaymentWays() {
		return paymentWays;
	}

	public void setmNationalCode(String mNationalCode) {
		this.mNationalCode = mNationalCode;
	}

	public String getmNationalCode() {
		return mNationalCode;
	}

	public void setmAreaCode(String mAreaCode) {
		this.mAreaCode = mAreaCode;
	}

	public String getmAreaCode() {
		return mAreaCode;
	}

	public void setmNumberPhone(String mNumberPhone) {
		this.mNumberPhone = mNumberPhone;
	}

	public String getmNumberPhone() {
		return mNumberPhone;
	}

	public void setpNationalCode(String pNationalCode) {
		this.pNationalCode = pNationalCode;
	}

	public String getpNationalCode() {
		return pNationalCode;
	}

	public void setpAreaCode(String pAreaCode) {
		this.pAreaCode = pAreaCode;
	}

	public String getpAreaCode() {
		return pAreaCode;
	}

	public void setpNumberPhone(String pNumberPhone) {
		this.pNumberPhone = pNumberPhone;
	}

	public String getpNumberPhone() {
		return pNumberPhone;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getEmail() {
		return email;
	}

	public void setConfirmationEmail(String confirmationEmail) {
		this.confirmationEmail = confirmationEmail;
	}

	public String getConfirmationEmail() {
		return confirmationEmail;
	}

	public List<SelectItem> getCardExpiredYears() {
		return cardExpiredYears;
	}

	public List<SelectItem> getGenders() {
		return genders;
	}

	public void setSelectedGender(String selectedGender) {
		this.selectedGender = selectedGender;
	}

	public String getSelectedGender() {
		return selectedGender;
	}
	
	public List<SelectItem> getNationalPhoneCodes() {
		return nationalPhoneCodes;
	}

	public void setSelectedNationalCode(String selectedNationalCode) {
		this.selectedNationalCode = selectedNationalCode;
	}

	public String getSelectedNationalCode() {
		return selectedNationalCode;
	}

	public void setSelectedBirthDay(Date selectedBirthDay) {
		this.selectedBirthDay = selectedBirthDay;
	}

	public Date getSelectedBirthDay() {
		return selectedBirthDay;
	}

	public void setSelectedPaymentCardExpired(Date selectedPaymentCardExpired) {
		this.selectedPaymentCardExpired = selectedPaymentCardExpired;
	}

	public Date getSelectedPaymentCardExpired() {
		return selectedPaymentCardExpired;
	}
}
